#ifndef _MYEXTEND_H
#define _MYEXTEND_H

#include "libavformat/avformat.h"
#include "libavformat/avio.h"
#include "libavcodec/avcodec.h"
#include "libavfilter/avfilter.h"
#include "libavfilter/avfiltergraph.h"
#include "libavutil/avutil.h"
#include "libavutil/dict.h"
#include "libavutil/fifo.h"
#include "libavutil/pixfmt.h"
#include "libavutil/rational.h"
#include "libswresample/swresample.h"

#define VSYNC_AUTO       -1
#define VSYNC_PASSTHROUGH 0
#define VSYNC_CFR         1
#define VSYNC_VFR         2
#define VSYNC_DROP        0xff

#define MAXNBSTREAMS 5

typedef struct tInputStream{
	AVStream *st;
	int decoding_needed;     /* true if the packets must be decoded in 'raw_fifo' */
	AVCodec *dec;
	AVFrame *decoded_frame;

	int64_t       start;     /* time when read started */

	    /* predicted dts of the next packet read for this stream or (when there are
	     * several frames in a packet) of the next frame in current packet (in AV_TIME_BASE units) */
	int64_t       next_dts;
	int64_t       dts;       ///< dts of the last packet read for this stream (in AV_TIME_BASE units)
	int64_t       next_pts;  ///< synthetic pts for the next decode frame (in AV_TIME_BASE units)
	int64_t       pts;       ///< current pts of the decoded frame  (in AV_TIME_BASE units)

	AVRational frame_rate;    /* framerate forced with -r */
}InputStream;

typedef struct tOutputStream{
	AVStream *st;            /* stream in the output file */
	int64_t first_pts;
	AVCodec *enc;
	AVFilterContext     *filter;
	AVBitStreamFilterContext *bitstream_filters;
	AVRational frame_rate;    /* framerate forced with -r */
	int stream_copy;
	int force_fps;
	int top_field_first;

	float frame_aspect_ratio;
	float last_quality;

	/* forced key frames */
	int64_t *forced_kf_pts;
	int forced_kf_count;
	int forced_kf_index;
	char *forced_keyframes;
}OutputStream;

typedef struct tCompressor{
	int nbStream;

	AVFormatContext *inFmtCtx;
	InputStream *inStreams[MAXNBSTREAMS];

	AVFormatContext *outFmtCtx;
	OutputStream *outStreams[MAXNBSTREAMS];
	int64_t recording_time;  ///< desired length of the resulting file in microseconds == AV_TIME_BASE units
	int64_t start_time;      ///< start time in microseconds == AV_TIME_BASE units
	enum PixelFormat output_pix_fmt;

	int video_sync_method;
	int audio_sync_method;
	int copy_tb;
	int audio_volume;
	int frame_bits_per_raw_sample;
}TCompressor;

int doTranscode(char *inputFile, char *outputFile);
int add_audio_stream(TCompressor *compressor, enum AVCodecID codec_id);
int add_video_stream(TCompressor *compressor, enum AVCodecID codec_id);
int write_frame(TCompressor *compressor, AVFormatContext *s, AVPacket *pkt, OutputStream *ost);
int output_video(AVFormatContext *s, OutputStream *ost, AVFrame *in_picture, float quality);
int output_audio(AVFormatContext *s, OutputStream *ost, AVFrame *frame);
int exit_program(int errorCode);
#endif
